import { deepClone, generateId, getDefaultFormConfig, overwriteObj, titleCase } from "@/utils/util"
import {
    containers,
    advancedFields,
    basicFields,
    dataBox,
    customFields,
    layoutFields,
} from "@/components/form-designer/widget-panel/widgetsConfig.js"
import { VARIANT_FORM_VERSION } from "@/utils/config"
import WidgetProperties from "@/components/form-designer/setting-panel/propertyRegister";

const { EVENT_PROPERTIES } = WidgetProperties;

export function createDesigner(vueInstance) {
    let defaultFormConfig = deepClone(getDefaultFormConfig())

    return {
        //组件集合
        widgetList: [],
        //form表单设置集合
        formConfig: { cssCode: '' },
        //数据源集合
        dataSource: [],
        //数据源数据集合
        dataSourceMap: {},
        //当前页面可编辑script脚本信息
        pageScript: {
            data: "",
            methods: [],
            mounted: "",
            created: "",
        },
        //组件内部script脚本,外部无法访问
        templateScript: {},
        //开启页面选择指定组件保存为自定义组件
        startSelect: false,
        //保存选择组件的数组
        selfComponent: [],
        //临时存储 被选中的组件及父级组件


        selectedId: null,
        selectedWidget: null,
        selectedWidgetName: null,  //选中组件名称（唯一）
        vueInstance: vueInstance,

        formWidget: null,  //表单设计容器

        cssClassList: [],  //自定义样式列表

        historyData: {
            index: -1,  //index: 0,
            maxStep: 20,
            steps: [],
        },
        attrList: [],
        colAttrList: [],
        entityList: [],
        loadingData: false,
        componentList: [], //自定义组件列表
        selfComponentObj: {}, //自定义组件对象

        //设置自定义组件
        setSelfComponent(obj) {
            if (this.selfComponent.length === 0) {
                this.selfComponent.push(obj)
            } else {
                let ids = this.selfComponent.map(i => i.id);
                if (!ids.includes(obj.id)) {
                    this.selfComponent.push(obj)
                } else {
                    let index = ids.indexOf(obj.id);
                    this.selfComponent.splice(index, 1)
                }
            }
        },

        // 初始化编辑器数据信息
        initDesigner(resetFormJson) {
            this.widgetList = []
            this.formConfig = deepClone(defaultFormConfig)

            //输出版本信息和语雀链接
            /* console.info(`%cVariantForm %cVer${VARIANT_FORM_VERSION} %chttps://www.yuque.com/visualdev/vform`,
                 "color:#409EFF;font-size: 22px;font-weight:bolder",
                 "color:#999;font-size: 12px",
                 "color:#333"
             )*/

            if (!resetFormJson) {
                this.initHistoryData()
            }
        },

        // 清除编辑器数据信息
        clearDesigner(skipHistoryChange) {
            let emptyWidgetListFlag = (this.widgetList.length === 0)
            this.widgetList = []
            this.dataSource = []
            this.dataSourceMap = []
            this.pageScript = {
                data: "",
                methods: [],
                mounted: "",
                created: ""
            }
            this.templateScript = {};
            this.selectedId = null
            this.selectedWidgetName = null
            this.selectedWidget = {}  //this.selectedWidget = null
            overwriteObj(this.formConfig, defaultFormConfig) //

            if (skipHistoryChange) {
                //什么也不做！！
            } else if (!emptyWidgetListFlag) {
                this.emitHistoryChange()
            } else {
                this.saveCurrentHistoryStep()
            }
        },

        loadPresetCssCode(preCssCode) {
            if ((this.formConfig.cssCode === '') && !!preCssCode) {
                this.formConfig.cssCode = preCssCode
            }
        },

        getLayoutType() {
            return this.formConfig.layoutType || 'PC'
        },

        changeLayoutType(newType) {
            this.formConfig.layoutType = newType
        },

        getImportTemplate() {
            return {
                widgetList: [],
                // formConfig: deepClone(this.formConfig)
                formConfig: deepClone(defaultFormConfig)
            }
        },

        loadFormJson(formJson) {
            let modifiedFlag = false
            if (!!formJson && !!formJson.widgetList) {
                this.formWidget.clearWidgetRefList()
                this.widgetList = formJson.widgetList
                modifiedFlag = true
            }
            if (!!formJson && !!formJson.formConfig) {
                //this.formConfig = importObj.formConfig
                overwriteObj(this.formConfig, formJson.formConfig)  /* 用=赋值，会导致inject依赖注入的formConfig属性变成非响应式 */
                modifiedFlag = true
            }
            if (!!formJson && !!formJson.dataSource) {
                this.dataSource = formJson.dataSource
            }

            if (!!formJson && !!formJson.pageScript) {
                this.pageScript = formJson.pageScript
            }

            if (!!formJson && !!formJson.templateScript) {
                this.templateScript = formJson.templateScript
            }

            if (modifiedFlag) {
                this.emitEvent('form-json-imported', [])  // 通知其他组件
            }

            return modifiedFlag
        },

        setSelected(selected) {
            if (!selected) {
                this.clearSelected()
                return
            }

            this.selectedWidget = selected
            if (selected.id) {
                this.selectedId = selected.id
                this.selectedWidgetName = selected.options.name
            }
        },

        updateSelectedWidgetNameAndLabel(selectedWidget, newName, newLabel) {
            this.selectedWidgetName = newName
            //selectedWidget.options.name = newName  //此行多余
            if (!!newLabel && (Object.keys(selectedWidget.options).indexOf('label') > -1)) {
                selectedWidget.options.label = newLabel
            }
        },

        clearSelected() {
            this.selectedId = null
            this.selectedWidgetName = null
            this.selectedWidget = {}  //this.selectedWidget = null
        },

        checkWidgetMove(evt) { /* Only field widget can be dragged into sub-form */
            if (!!evt.draggedContext && !!evt.draggedContext.element) {
                let wgCategory = evt.draggedContext.element.category
                let wgType = evt.draggedContext.element.type
                if (evt.to) {
                    if ((evt.to.className === 'sub-form-table') && (wgCategory === 'container')) {
                        //this.$message.info(this.vueInstance.i18nt('designer.hint.onlyFieldWidgetAcceptable'))
                        return false
                    }
                }
            }

            return true
        },

        checkFieldMove(evt) {
            if (!!evt.draggedContext && !!evt.draggedContext.element) {
                let wgCategory = evt.draggedContext.element.category
                let wgType = evt.draggedContext.element.type + ''
                if (evt.to) {
                    if ((evt.to.className === 'sub-form-table') && (wgType === 'slot')) {
                        //this.$message.info(this.vueInstance.i18nt('designer.hint.onlyFieldWidgetAcceptable'))
                        return false
                    }
                }
            }

            return true
        },

        /**
         * 追加表格新行
         * @param widget
         */
        appendTableRow(widget) {
            let rowIdx = widget.rows.length//确定插入行位置
            let newRow = deepClone(widget.rows[widget.rows.length - 1])
            newRow.id = 'table-row-' + generateId()
            newRow.merged = false
            newRow.cols.forEach(col => {
                col.id = 'table-cell-' + generateId()
                col.options.name = col.id
                col.merged = false
                col.options.colspan = 1
                col.options.rowspan = 1
                col.widgetList.length = 0
            })
            widget.rows.splice(rowIdx, 0, newRow)

            this.emitHistoryChange()
        },

        /**
         * 追加表格新列
         * @param widget
         */
        appendTableCol(widget) {
            let colIdx = widget.rows[0].cols.length  //确定插入列位置
            widget.rows.forEach(row => {
                let newCol = deepClone(this.getContainerByType('table-cell'))
                newCol.id = 'table-cell-' + generateId()
                newCol.options.name = newCol.id
                newCol.merged = false
                newCol.options.colspan = 1
                newCol.options.rowspan = 1
                newCol.widgetList.length = 0
                row.cols.splice(colIdx, 0, newCol)
            })

            this.emitHistoryChange()
        },

        insertTableRow(widget, insertPos, cloneRowIdx, curCol, aboveFlag) {
            let newRowIdx = aboveFlag ? insertPos : (insertPos + 1)  //初步确定插入行位置
            if (!aboveFlag) {  //继续向下寻找同列第一个未被合并的单元格
                let tmpRowIdx = newRowIdx
                let rowFoundFlag = false
                while (tmpRowIdx < widget.rows.length) {
                    if (!widget.rows[tmpRowIdx].cols[curCol].merged) {
                        newRowIdx = tmpRowIdx
                        rowFoundFlag = true
                        break
                    } else {
                        tmpRowIdx++
                    }
                }

                if (!rowFoundFlag) {
                    newRowIdx = widget.rows.length
                }
            }

            let newRow = deepClone(widget.rows[cloneRowIdx])
            newRow.id = 'table-row-' + generateId()
            newRow.merged = false
            newRow.cols.forEach(col => {
                col.id = 'table-cell-' + generateId()
                col.options.name = col.id
                col.merged = false
                col.options.colspan = 1
                col.options.rowspan = 1
                col.widgetList.length = 0
            })
            widget.rows.splice(newRowIdx, 0, newRow)

            let colNo = 0
            while ((newRowIdx < widget.rows.length - 1) && (colNo < widget.rows[0].cols.length)) {  //越界判断
                const cellOfNextRow = widget.rows[newRowIdx + 1].cols[colNo]
                const rowMerged = cellOfNextRow.merged  //确定插入位置下一行的单元格是否为合并单元格
                if (rowMerged) {
                    let rowArray = widget.rows
                    let unMergedCell = {}
                    let startRowIndex = null
                    for (let i = newRowIdx; i >= 0; i--) {  //查找该行已合并的主单元格
                        if (!rowArray[i].cols[colNo].merged && (rowArray[i].cols[colNo].options.rowspan > 1)) {
                            startRowIndex = i
                            unMergedCell = rowArray[i].cols[colNo]
                            break
                        }
                    }

                    if (unMergedCell.options) {  //如果有符合条件的unMergedCell
                        let newRowspan = unMergedCell.options.rowspan + 1
                        this.setPropsOfMergedRows(widget.rows, startRowIndex, colNo, unMergedCell.options.colspan, newRowspan)
                        colNo += unMergedCell.options.colspan
                    } else {
                        colNo += 1
                    }
                } else {
                    //colNo += 1
                    colNo += cellOfNextRow.options.colspan || 1
                }
            }

            this.emitHistoryChange()
        },

        insertTableCol(widget, insertPos, curRow, leftFlag) {
            let newColIdx = leftFlag ? insertPos : (insertPos + 1)  //初步确定插入列位置
            if (!leftFlag) {  //继续向右寻找同行第一个未被合并的单元格
                let tmpColIdx = newColIdx
                let colFoundFlag = false
                while (tmpColIdx < widget.rows[curRow].cols.length) {
                    if (!widget.rows[curRow].cols[tmpColIdx].merged) {
                        newColIdx = tmpColIdx
                        colFoundFlag = true
                        break
                    } else {
                        tmpColIdx++
                    }

                    if (!colFoundFlag) {
                        newColIdx = widget.rows[curRow].cols.length
                    }
                }
            }

            widget.rows.forEach(row => {
                let newCol = deepClone(this.getContainerByType('table-column'))
                newCol.id = 'table-column-' + generateId()
                newCol.options.name = newCol.id
                newCol.merged = false
                newCol.options.colspan = 1
                newCol.options.rowspan = 1
                newCol.widgetList.length = 0
                row.cols.splice(newColIdx, 0, newCol)
            })

            let rowNo = 0
            while ((newColIdx < widget.rows[0].cols.length - 1) && (rowNo < widget.rows.length)) {  //越界判断
                const cellOfNextCol = widget.rows[rowNo].cols[newColIdx + 1]
                const colMerged = cellOfNextCol.merged  //确定插入位置右侧列的单元格是否为合并单元格
                if (colMerged) {
                    let colArray = widget.rows[rowNo].cols
                    let unMergedCell = {}
                    let startColIndex = null
                    for (let i = newColIdx; i >= 0; i--) {  //查找该行已合并的主单元格
                        if (!colArray[i].merged && (colArray[i].options.colspan > 1)) {
                            startColIndex = i
                            unMergedCell = colArray[i]
                            break
                        }
                    }

                    if (unMergedCell.options) {  //如果有符合条件的unMergedCell
                        let newColspan = unMergedCell.options.colspan + 1
                        this.setPropsOfMergedCols(widget.rows, rowNo, startColIndex, newColspan, unMergedCell.options.rowspan)
                        rowNo += unMergedCell.options.rowspan
                    } else {
                        rowNo += 1
                    }
                } else {
                    //rowNo += 1
                    rowNo += cellOfNextCol.options.rowspan || 1
                }
            }

            this.emitHistoryChange()
        },

        setPropsOfMergedCols(rowArray, startRowIndex, startColIndex, newColspan, rowspan) {
            for (let i = startRowIndex; i < startRowIndex + rowspan; i++) {
                for (let j = startColIndex; j < startColIndex + newColspan; j++) {
                    if ((i === startRowIndex) && (j === startColIndex)) {
                        rowArray[i].cols[j].options.colspan = newColspan  //合并后的主单元格
                        continue
                    }

                    rowArray[i].cols[j].merged = true
                    rowArray[i].cols[j].options.colspan = newColspan
                    rowArray[i].cols[j].widgetList = []
                }
            }
        },

        setPropsOfMergedRows(rowArray, startRowIndex, startColIndex, colspan, newRowspan) {
            for (let i = startRowIndex; i < startRowIndex + newRowspan; i++) {
                for (let j = startColIndex; j < startColIndex + colspan; j++) {
                    if ((i === startRowIndex) && (j === startColIndex)) {
                        rowArray[i].cols[j].options.rowspan = newRowspan
                        continue
                    }

                    rowArray[i].cols[j].merged = true
                    rowArray[i].cols[j].options.rowspan = newRowspan
                    rowArray[i].cols[j].widgetList = []
                }
            }
        },

        setPropsOfSplitCol(rowArray, startRowIndex, startColIndex, colspan, rowspan) {
            for (let i = startRowIndex; i < startRowIndex + rowspan; i++) {
                for (let j = startColIndex; j < startColIndex + colspan; j++) {
                    rowArray[i].cols[j].merged = false;
                    rowArray[i].cols[j].options.rowspan = 1
                    rowArray[i].cols[j].options.colspan = 1
                }
            }
        },

        setPropsOfSplitRow(rowArray, startRowIndex, startColIndex, colspan, rowspan) {
            for (let i = startRowIndex; i < startRowIndex + rowspan; i++) {
                for (let j = startColIndex; j < startColIndex + colspan; j++) {
                    rowArray[i].cols[j].merged = false;
                    rowArray[i].cols[j].options.rowspan = 1
                    rowArray[i].cols[j].options.colspan = 1
                }
            }
        },

        mergeTableCol(rowArray, colArray, curRow, curCol, leftFlag, cellWidget) {
            let mergedColIdx = leftFlag ? curCol : curCol + colArray[curCol].options.colspan

            // let remainedColIdx = !!leftFlag ? curCol - colArray[curCol - 1].options.colspan : curCol
            let remainedColIdx = leftFlag ? curCol - 1 : curCol
            if (leftFlag) {  //继续向左寻找同行未被合并的第一个单元格
                let tmpColIdx = remainedColIdx
                while (tmpColIdx >= 0) {
                    if (!rowArray[curRow].cols[tmpColIdx].merged) {
                        remainedColIdx = tmpColIdx
                        break;
                    } else {
                        tmpColIdx--
                    }
                }
            }

            if (!!colArray[mergedColIdx].widgetList && (colArray[mergedColIdx].widgetList.length > 0)) { //保留widgetList
                if (!colArray[remainedColIdx].widgetList || (colArray[remainedColIdx].widgetList.length === 0)) {
                    colArray[remainedColIdx].widgetList = deepClone(colArray[mergedColIdx].widgetList)
                }
            }

            let newColspan = colArray[mergedColIdx].options.colspan * 1 + colArray[remainedColIdx].options.colspan * 1
            this.setPropsOfMergedCols(rowArray, curRow, remainedColIdx, newColspan, cellWidget.options.rowspan)

            this.emitHistoryChange()
        },

        mergeTableWholeRow(rowArray, colArray, rowIndex, colIndex) { //需要考虑操作的行存在已合并的单元格！！
            //整行所有单元格行高不一致不可合并！！
            let startRowspan = rowArray[rowIndex].cols[0].options.rowspan
            let unmatchedFlag = false
            for (let i = 1; i < rowArray[rowIndex].cols.length; i++) {
                if (rowArray[rowIndex].cols[i].options.rowspan !== startRowspan) {
                    unmatchedFlag = true
                    break;
                }
            }
            if (unmatchedFlag) {
                this.vueInstance.$message.info(this.vueInstance.i18nt('designer.hint.rowspanNotConsistentForMergeEntireRow'))
                return
            }

            let widgetListCols = colArray.filter((colItem) => {
                return !colItem.merged && !!colItem.widgetList && (colItem.widgetList.length > 0)
            })
            if (!!widgetListCols && (widgetListCols.length > 0)) { //保留widgetList
                if ((widgetListCols[0].id !== colArray[0].id) && (!colArray[0].widgetList ||
                    colArray[0].widgetList.length <= 0)) {
                    colArray[0].widgetList = deepClone(widgetListCols[0].widgetList)
                }
            }

            this.setPropsOfMergedCols(rowArray, rowIndex, 0, colArray.length, colArray[colIndex].options.rowspan)

            this.emitHistoryChange()
        },

        mergeTableRow(rowArray, curRow, curCol, aboveFlag, cellWidget) {
            let mergedRowIdx = aboveFlag ? curRow : curRow + cellWidget.options.rowspan

            //let remainedRowIdx = !!aboveFlag ? curRow - cellWidget.options.rowspan : curRow
            let remainedRowIdx = aboveFlag ? curRow - 1 : curRow
            if (aboveFlag) {  //继续向上寻找同列未被合并的第一个单元格
                let tmpRowIdx = remainedRowIdx
                while (tmpRowIdx >= 0) {
                    if (!rowArray[tmpRowIdx].cols[curCol].merged) {
                        remainedRowIdx = tmpRowIdx
                        break;
                    } else {
                        tmpRowIdx--
                    }
                }
            }

            if (!!rowArray[mergedRowIdx].cols[curCol].widgetList && (rowArray[mergedRowIdx].cols[curCol].widgetList.length > 0)) { //保留widgetList
                if (!rowArray[remainedRowIdx].cols[curCol].widgetList || (rowArray[remainedRowIdx].cols[curCol].widgetList.length === 0)) {
                    rowArray[remainedRowIdx].cols[curCol].widgetList = deepClone(rowArray[mergedRowIdx].cols[curCol].widgetList)
                }
            }

            let newRowspan = rowArray[mergedRowIdx].cols[curCol].options.rowspan * 1 + rowArray[remainedRowIdx].cols[curCol].options.rowspan * 1
            this.setPropsOfMergedRows(rowArray, remainedRowIdx, curCol, cellWidget.options.colspan, newRowspan)

            this.emitHistoryChange()
        },

        mergeTableWholeCol(rowArray, colArray, rowIndex, colIndex) { //需要考虑操作的列存在已合并的单元格！！
            //整列所有单元格列宽不一致不可合并！！
            let startColspan = rowArray[0].cols[colIndex].options.colspan
            let unmatchedFlag = false
            for (let i = 1; i < rowArray.length; i++) {
                if (rowArray[i].cols[colIndex].options.colspan !== startColspan) {
                    unmatchedFlag = true
                    break;
                }
            }
            if (unmatchedFlag) {
                this.vueInstance.$message.info(this.vueInstance.i18nt('designer.hint.colspanNotConsistentForMergeEntireColumn'))
                return
            }

            let widgetListCols = []
            rowArray.forEach(rowItem => {
                let tempCell = rowItem.cols[colIndex]
                if (!tempCell.merged && !!tempCell.widgetList && (tempCell.widgetList.length > 0)) {
                    widgetListCols.push(tempCell)
                }
            })

            let firstCellOfCol = rowArray[0].cols[colIndex]
            if (!!widgetListCols && (widgetListCols.length > 0)) { //保留widgetList
                if ((widgetListCols[0].id !== firstCellOfCol.id) && (!firstCellOfCol.widgetList ||
                    firstCellOfCol.widgetList.length <= 0)) {
                    firstCellOfCol.widgetList = deepClone(widgetListCols[0].widgetList)
                }
            }

            this.setPropsOfMergedRows(rowArray, 0, colIndex, firstCellOfCol.options.colspan, rowArray.length)

            this.emitHistoryChange()
        },

        undoMergeTableCol(rowArray, rowIndex, colIndex, colspan, rowspan) {
            this.setPropsOfSplitCol(rowArray, rowIndex, colIndex, colspan, rowspan)

            this.emitHistoryChange()
        },

        undoMergeTableRow(rowArray, rowIndex, colIndex, colspan, rowspan) {
            this.setPropsOfSplitRow(rowArray, rowIndex, colIndex, colspan, rowspan)

            this.emitHistoryChange()
        },

        deleteTableWholeCol(rowArray, colIndex) { //需考虑删除的是合并列！！
            console.log('rowArray, colIndex',rowArray, colIndex)
            let onlyOneColFlag = true;
            // 删除最后一个
            // if(colIndex ===rowArray[0].cols.length ){
            //     this.selectedWidget&&this.selectedWidget(rowArray[0].cols[colIndex-1]);
            // }else{
            //     this.selectedWidget&&this.selectedWidget(rowArray[0].cols[colIndex+1]);

            // }
            rowArray.forEach(ri => {
                if (ri.cols[0].options.colspan !== rowArray[0].cols.length) {
                    onlyOneColFlag = false
                }
            })
            //仅剩一列则不可删除！！
            if (onlyOneColFlag) {
                this.vueInstance.$message.info(this.vueInstance.i18nt('designer.hint.lastColCannotBeDeleted'))
                return
            }

            //整列所有单元格列宽不一致不可删除！！
            let startColspan = rowArray[0].cols[colIndex].options.colspan
            let unmatchedFlag = false
            for (let i = 1; i < rowArray.length; i++) {
                if (rowArray[i].cols[colIndex].options.colspan !== startColspan) {
                    unmatchedFlag = true
                    break;
                }
            }
            if (unmatchedFlag) {
                this.vueInstance.$message.info(this.vueInstance.i18nt('designer.hint.colspanNotConsistentForDeleteEntireColumn'))
                return
            }

            rowArray.forEach((rItem) => {
                rItem.cols.splice(colIndex, startColspan)
            })

            this.emitHistoryChange()
        },

        deleteTableWholeRow(rowArray, rowIndex) { //需考虑删除的是合并行！！
            let onlyOneRowFlag = true
            rowArray[0].cols.forEach(ci => {
                if (ci.options.rowspan !== rowArray.length) {
                    onlyOneRowFlag = false
                }
            })
            //仅剩一行则不可删除！！
            if (onlyOneRowFlag) {
                this.vueInstance.$message.info(this.vueInstance.i18nt('designer.hint.lastRowCannotBeDeleted'))
                return
            }

            //整行所有单元格行高不一致不可删除！！
            let startRowspan = rowArray[rowIndex].cols[0].options.rowspan
            let unmatchedFlag = false
            for (let i = 1; i < rowArray[rowIndex].cols.length; i++) {
                if (rowArray[rowIndex].cols[i].options.rowspan !== startRowspan) {
                    unmatchedFlag = true
                    break;
                }
            }
            if (unmatchedFlag) {
                this.vueInstance.$message.info(this.vueInstance.i18nt('designer.hint.rowspanNotConsistentForDeleteEntireRow'))
                return
            }

            rowArray.splice(rowIndex, startRowspan)

            this.emitHistoryChange()
        },

        getContainerByType(typeName) {
            let allWidgets = [...containers, ...basicFields, ...dataBox, ...advancedFields,...layoutFields, ...customFields]
            let foundCon = null
            allWidgets.forEach(con => {
                if (!!con.category && !!con.type && (con.type === typeName)) {
                    foundCon = con
                }
            })
            return foundCon
        },

        getFieldWidgetByType(typeName) {
            let allWidgets = [...containers, ...basicFields, ...dataBox, ...advancedFields,...layoutFields, ...customFields]
            let foundWidget = null
            allWidgets.forEach(widget => {
                if (!widget.category && !!widget.type && (widget.type === typeName)) {
                    foundWidget = widget
                }
            })

            return foundWidget
        },

        hasConfig(widget, configName) {
            let originalWidget = null
            if (widget.category) {
                originalWidget = this.getContainerByType(widget.type)
            } else {
                originalWidget = this.getFieldWidgetByType(widget.type)
            }

            if (!originalWidget || !originalWidget.options) {
                return false
            }

            return Object.keys(originalWidget.options).indexOf(configName) > -1
        },

        upgradeWidgetConfig(oldWidget) {
            let newWidget = null
            if (oldWidget.category) {
                newWidget = this.getContainerByType(oldWidget.type)
            } else {
                newWidget = this.getFieldWidgetByType(oldWidget.type)
            }

            if (!newWidget || !newWidget.options) {
                return
            }

            Object.keys(newWidget.options).forEach(ck => {
                if (!oldWidget.hasOwnProperty(ck)) {
                    oldWidget.options[ck] = deepClone(newWidget.options[ck])
                }
            })
        },

        upgradeFormConfig(oldFormConfig) {
            Object.keys(this.formConfig).forEach(fc => {
                if (!oldFormConfig.hasOwnProperty(fc)) {
                    oldFormConfig[fc] = deepClone(this.formConfig[fc])
                }
            })
        },

        cloneGridCol(widget, parentWidget) {
            let newGridCol = deepClone(this.getContainerByType('grid-col'))
            newGridCol.options.span = widget.options.span
            let tmpId = generateId()
            newGridCol.id = 'grid-col-' + tmpId
            newGridCol.options.name = 'gridCol' + tmpId

            parentWidget.cols.push(newGridCol)
        },

        cloneContainer(containWidget) {
            if (containWidget.type === 'grid') {
                let newGrid = deepClone(this.getContainerByType('grid'))
                newGrid.id = newGrid.type + generateId()
                newGrid.options.name = newGrid.id
                containWidget.cols.forEach(gridCol => {
                    let newGridCol = deepClone(this.getContainerByType('grid-col'))
                    let tmpId = generateId()
                    newGridCol.id = 'grid-col-' + tmpId
                    newGridCol.options.name = 'gridCol' + tmpId
                    newGridCol.options.span = gridCol.options.span
                    newGrid.cols.push(newGridCol)
                })

                return newGrid
            } else if (containWidget.type === 'table') {
                let newTable = deepClone(this.getContainerByType('table'))
                newTable.id = newTable.type + generateId()
                newTable.options.name = newTable.id
                containWidget.rows.forEach(tRow => {
                    let newRow = deepClone(tRow)
                    newRow.id = 'table-row-' + generateId()
                    newRow.cols.forEach(col => {
                        col.id = 'table-cell-' + generateId()
                        col.options.name = col.id
                        col.widgetList = []  //清空组件列表
                    })
                    newTable.rows.push(newRow)
                })

                return newTable
            } else if (containWidget.type === 'data-column') {
                let newTable = deepClone(this.getContainerByType('data-column'))
                newTable.id = newTable.type + generateId()
                newTable.options.name = newTable.id
                containWidget.rows.forEach(tRow => {
                    let newRow = deepClone(tRow)
                    newRow.id = 'table-row-' + generateId()
                    newRow.cols.forEach(col => {
                        col.id = 'table-column-' + generateId()
                        col.options.name = col.id
                        col.widgetList = []  //清空组件列表
                    })
                    newTable.rows.push(newRow)
                })

                return newTable
            }else {  //其他容器组件不支持clone操作
                return null
            }
        },

        moveUpWidget(parentList, indexOfParentList) {
            if (parentList) {
                if (indexOfParentList === 0) {
                    this.vueInstance.$message(this.vueInstance.i18nt('designer.hint.moveUpFirstChildHint'))
                    return
                }

                let tempWidget = parentList[indexOfParentList]
                parentList.splice(indexOfParentList, 1)
                parentList.splice(indexOfParentList - 1, 0, tempWidget)
            }
        },

        moveDownWidget(parentList, indexOfParentList) {
            if (parentList) {
                if (indexOfParentList === parentList.length - 1) {
                    this.vueInstance.$message(this.vueInstance.i18nt('designer.hint.moveDownLastChildHint'))
                    return
                }

                let tempWidget = parentList[indexOfParentList]
                parentList.splice(indexOfParentList, 1)
                parentList.splice(indexOfParentList + 1, 0, tempWidget)
            }
        },

        copyNewFieldWidget(origin) {
            let newWidget = deepClone(origin);
            let tempId = generateId()
            if (newWidget.options && newWidget.options.hasOwnProperty("ref")) {
                let tempId = generateId()
                newWidget.options.ref = newWidget.type.replace(/-/g, '') + '_' + tempId
            }
            newWidget.id = newWidget.type.replace(/-/g, '') + tempId
            newWidget.options.name = newWidget.id
            newWidget.options.label = newWidget.options.label || newWidget.type.toLowerCase()

            delete newWidget.displayName
            return newWidget
        },


        replaceWidget(parentList, indexOfParentList, newData, parentId) {
            if (parentList) {
                let tempWidget = this.getWidgetByType(newData, parentId);

                if (!tempWidget) {
                    return;
                }
                parentList.splice(indexOfParentList, 1, tempWidget)
                this.setSelected(tempWidget)
            }
        },
        resetId(obj, eventKey, onlyId) {
            function reset(obj) {
                // 如果传入的不是对象类型，则直接返回
                if (typeof obj !== 'object' || obj === null) {
                    return obj;
                }
                // 定义一个返回的变量
                let copy = {};
                // 判断传入的对象是数组还是对象
                if (obj.constructor === Array) {
                    copy = [];
                }
                // 遍历对象的属性
                for (let key in obj) {
                    // 判断对象是否有该属性
                    if (obj.hasOwnProperty(key)) {
                        // 如果该属性是对象类型，则递归调用该函数
                        if (typeof obj[key] === 'object' && obj[key] !== null) {
                            if (key === "id") {
                                // 重置所有组件Id
                                copy[key] = obj.type.replace(/-/g, '') + generateId()
                            } else if (eventKey.includes(key)) {
                                // 对于多组件生成多个命名空间
                                copy[key] = obj[key] + onlyId
                            } else if (["visible", "dataSource"].includes(key)) {
                                copy[key] = obj[key] + onlyId
                            } else {
                                copy[key] = reset(obj[key]);
                            }
                        } else {
                            // 否则，直接复制属性值
                            if (key === "id") {
                                copy[key] = obj.type.replace(/-/g, '') + generateId()
                            } else if (eventKey.includes(key)) {
                                copy[key] = obj[key] + onlyId
                            } else if (["visible", "dataSource"].includes(key)) {
                                copy[key] = obj[key] + onlyId
                            } else {
                                copy[key] = obj[key];
                            }
                        }
                    }
                }
                return copy;
            }

            return reset(obj)
        },

        addToPage(templateScript, widgetList) {
            let obj = {};
            if (this.pageScript.data) {
              Object.assign(obj, JSON.parse(this.pageScript.data))
            }
            if (templateScript.data) {
              Object.assign(obj, JSON.parse(templateScript.data))
            }
      
            let methods = [];
            if (this.pageScript.methods.length > 0) {
              methods.push(...this.pageScript.methods)
            }
            if (templateScript.methods) {
              methods.push(...templateScript.methods)
            }
      
            let dataSource = [];
            if (this.dataSource.length > 0) {
              dataSource.push(...this.dataSource)
            }
            if (templateScript.dataSource.length > 0) {
              dataSource.push(...templateScript.dataSource)
            }
      
            this.pageScript.data = JSON.stringify(obj, null, 2)
            this.pageScript.mounted += templateScript.mounted + ";";
            this.pageScript.created += templateScript.created + ";";
            this.pageScript.methods = methods;
            this.dataSource = dataSource;
            return widgetList;
          },

        // 根据自定义组件
        addSelfField(temp) {
            let eventKey = Object.keys(EVENT_PROPERTIES);
            let onlyId =  generateId();
            let json = JSON.parse(temp)
            let templateScript = json["templateScript"];
            // 事件、脚本处理
            let widgetList = this.resetId(json.widgetList, eventKey, onlyId)
            let data = JSON.parse(templateScript.data);
            let funNameList = templateScript.methods.map(i => i.funName);
            let replaceList = [...Object.keys(data), ...funNameList]

            let dataSourceNameList = templateScript.dataSource.map(i => i.name);

            templateScript.methods.forEach(i => {
                i.funName = i.funName + onlyId;
                for (let j = 0; j < replaceList.length; j++) {
                    let item = replaceList[j];
                    const regex = new RegExp('(?<![A-Za-z0-9_])' + item + '(?![A-Za-z0-9_])', 'g');
                    i.funBody = i.funBody.replace(regex, item + onlyId)
                    templateScript.data = templateScript.data.replace(regex, item + onlyId)
                    templateScript.mounted = templateScript.mounted.replace(regex, item + onlyId)
                    templateScript.created = templateScript.created.replace(regex, item + onlyId)
                }
            })

            //处理数据源名称
            let dataSourceObj = ['dataSourceMethods', "dataSourceMapData"];
            templateScript.methods.forEach(i => {
                for (let j = 0; j < dataSourceNameList.length; j++) {
                    let item = dataSourceNameList[j];
                    for (let k = 0; k < dataSourceObj.length; k++) {
                        let m = dataSourceObj[k];
                        const regex_1 = new RegExp('this.' + m + '.' + item + '(?![A-Za-z0-9_])', 'g');
                        i.funBody = i.funBody.replace(regex_1, `this.${m}.${item + onlyId}`)
                            .replace(`this.${m}['${item}']`, `this.${m}['${item + onlyId}']`)
                            .replace(`this.${m}["${item}"]`, `this.${m}["${item + onlyId}"]`)

                        templateScript.mounted = templateScript.mounted.replace(regex_1, `this.${m}.${item + onlyId}`)
                            .replace(`this.${m}['${item}']`, `this.${m}['${item + onlyId}']`)
                            .replace(`this.${m}["${item}"]`, `this.${m}["${item + onlyId}"]`)

                        templateScript.created = templateScript.created.replace(regex_1, `this.${m}.${item + onlyId}`)
                            .replace(`this.${m}['${item}']`, `this.${m}['${item + onlyId}']`)
                            .replace(`this.${m}["${item}"]`, `this.${m}["${item + onlyId}"]`)
                    }
                }
            })

            templateScript.dataSource.forEach(i => {
                i.name += onlyId;
            })

            return this.addToPage(templateScript, widgetList);
        },
        // 根据属性类型生成组件
        getWidgetByType(v, parentId) {
            const selectedId = v.parentId || parentId;
            let newWidget = null;
            let tempId = generateId();
            // 判断属性是否是自定义模板
            if (this.selfComponentObj[v.attributeTypeName]) {
                newWidget= this.addSelfField(this.selfComponentObj[v.attributeTypeName]);
                return this.addButtonWidget(newWidget);
            }
            if (!v.columnType) {
                newWidget = null
            }
            // 字符串
            if (v.columnType === 'string') {
                if (v.attributeTypeName === 'enum') {
                    newWidget = {
                        type: 'select',
                        icon: 'select-field',
                        formItemFlag: true,
                        id: "select" + tempId,
                        options: {
                            name: selectedId ? `${selectedId}_${v.columnName}` : v.columnName,
                            parentId: v.parentId || selectedId,
                            placeholder: v.nameEn,
                            label: v.nameCn,
                            fieldAttribute: v.columnName,
                            labelAlign: 'label-right-align',
                            defaultValue: '',
                            placeholder: '',
                            columnWidth: '200px',
                            size: '',
                            labelWidth: null,
                            labelHidden: false,
                            disabled: false,
                            hidden: false,
                            clearable: true,
                            filterable: false,
                            allowCreate: false,
                            remote: false,
                            automaticDropdown: false,  //自动下拉
                            multiple: false,
                            multipleLimit: 0,
                            apiData: '',
                            apiCode: v.columnName,
                            value_: "value",
                            label_: "name",
                            optionItems: [
                                { label: 'select 1', value: 1 },
                                { label: 'select 2', value: 2 },
                                { label: 'select 3', value: 3 },
                            ],
                            required: false,
                            requiredHint: '',
                            validation: '',
                            validationHint: '',
                            //-------------------
                            customClass: '',  //自定义css类名
                            labelIconClass: null,
                            labelIconPosition: 'rear',
                            labelTooltip: null,
                            //-------------------
                            onCreated: '',
                            onMounted: '',
                            onRemoteQuery: '',
                            onChange: '',
                            onFocus: '',
                            onBlur: '',
                            onValidate: '',
                        },
                    }
                } else {
                    newWidget =
                    {
                        type: 'input',
                        icon: 'text-field',
                        formItemFlag: true,
                        id: "input" + tempId,
                        options: {
                            name: selectedId ? `${selectedId}_${v.columnName}` : v.columnName,
                            parentId: v.parentId || selectedId,
                            placeholder: v.nameEn,
                            label: v.nameCn,
                            fieldAttribute: v.columnName,
                            labelAlign: 'label-right-align',
                            type: 'text',
                            defaultValue: '',
                            columnWidth: '200px',
                            size: '',
                            labelWidth: null,
                            labelHidden: false,
                            readonly: false,
                            disabled: false,
                            hidden: false,
                            clearable: true,
                            showPassword: false,
                            required: false,
                            requiredHint: '',
                            inputType: v.attributeTypeName,
                            validation: v.columnValidation || v.attributeTypeName,
                            validationHint: '',
                            //-------------------
                            customClass: '',  //自定义css类名
                            labelIconClass: null,
                            labelIconPosition: 'rear',
                            labelTooltip: null,
                            minLength: null,
                            maxLength: null,
                            showWordLimit: false,
                            prefixIcon: '',
                            suffixIcon: '',
                            appendButton: false,
                            appendButtonDisabled: false,
                            buttonIcon: 'el-icon-search',
                            //-------------------
                            onCreated: '',
                            onMounted: '',
                            onInput: '',
                            onChange: '',
                            onFocus: '',
                            onBlur: '',
                            onValidate: '',
                            onAppendButtonClick: '',


                        },
                    }
                }

            }
            // 小数
            if (v.columnType === 'decimal') {
                newWidget =
                {
                    type: 'input',
                    icon: 'text-field',
                    formItemFlag: true,
                    id: "input" + tempId,
                    options: {
                        name: selectedId ? `${selectedId}_${v.columnName}` : v.columnName,
                        parentId: v.parentId || selectedId,
                        placeholder: v.nameEn,
                        label: v.nameCn,
                        fieldAttribute: v.columnName,
                        labelAlign: 'label-right-align',
                        type: 'text',
                        defaultValue: '',
                        columnWidth: '200px',
                        size: '',
                        labelWidth: null,
                        labelHidden: false,
                        readonly: false,
                        disabled: false,
                        hidden: false,
                        clearable: true,
                        showPassword: false,
                        required: false,
                        requiredHint: '',
                        inputType: v.attributeTypeName,
                        validation: v.columnValidation || v.attributeTypeName,
                        validationHint: '',
                        //-------------------
                        customClass: '',  //自定义css类名
                        labelIconClass: null,
                        labelIconPosition: 'rear',
                        labelTooltip: null,
                        minLength: null,
                        maxLength: null,
                        showWordLimit: false,
                        prefixIcon: '',
                        suffixIcon: '',
                        appendButton: false,
                        appendButtonDisabled: false,
                        buttonIcon: 'el-icon-search',
                        //-------------------
                        onCreated: '',
                        onMounted: '',
                        onInput: '',
                        onChange: '',
                        onFocus: '',
                        onBlur: '',
                        onValidate: '',
                        onAppendButtonClick: '',


                    },
                }
            }
            // 数字
            if (v.columnType === 'number') {
                newWidget =
                {
                    type: 'number',
                    icon: 'number-field',
                    formItemFlag: true,
                    id: "number" + tempId,
                    options: {
                        name: selectedId ? `${selectedId}_${v.columnName}` : v.columnName,
                        parentId: v.parentId || selectedId,
                        placeholder: v.nameEn,
                        label: v.nameCn,
                        fieldAttribute: v.columnName,
                        labelAlign: 'label-right-align',
                        defaultValue: 0,
                        columnWidth: '200px',
                        size: '',
                        labelWidth: null,
                        labelHidden: false,
                        disabled: false,
                        hidden: false,
                        required: false,
                        requiredHint: '',
                        validation: v.columnValidation || v.attributeTypeName,
                        validationHint: '',
                        //-------------------
                        customClass: '',  //自定义css类名
                        labelIconClass: null,
                        labelIconPosition: 'rear',
                        labelTooltip: null,
                        min: -100000000000,
                        max: 100000000000,
                        precision: 0,
                        step: 1,
                        controlsPosition: 'right',
                        //-------------------
                        onCreated: '',
                        onMounted: '',
                        onChange: '',
                        onFocus: '',
                        onBlur: '',
                        onValidate: '',
                    },
                }
            }

            // 日期
            if (v.columnType === 'date') {
                // time date datetime
                if (v.attributeTypeName === 'date') {
                    newWidget =
                    {
                        type: 'date',
                        icon: 'date-field',
                        formItemFlag: true,
                        id: "number" + tempId,
                        options: {
                            name: selectedId ? `${selectedId}_${v.columnName}` : v.columnName,
                            parentId: v.parentId || selectedId,
                            label: v.nameCn,
                            fieldAttribute: v.columnName,
                            labelAlign: 'label-right-align',
                            type: 'date',
                            defaultValue: null,
                            placeholder: '',
                            columnWidth: '200px',
                            size: '',
                            labelWidth: null,
                            labelHidden: false,
                            readonly: false,
                            disabled: false,
                            hidden: false,
                            clearable: true,
                            editable: false,
                            format: 'yyyy-MM-dd',  //日期显示格式
                            valueFormat: 'yyyy-MM-dd',  //日期对象格式
                            required: false,
                            requiredHint: '',
                            validation: v.columnValidation || v.attributeTypeName,
                            validationHint: '',
                            //-------------------
                            customClass: '',  //自定义css类名
                            labelIconClass: null,
                            labelIconPosition: 'rear',
                            labelTooltip: null,
                            //-------------------
                            onCreated: '',
                            onMounted: '',
                            onChange: '',
                            onFocus: '',
                            onBlur: '',
                            onValidate: '',
                        },
                    }
                }
                if (v.attributeTypeName === 'time') {
                    newWidget = {
                        type: 'time',
                        icon: 'time-field',
                        formItemFlag: true,
                        id: "time" + tempId,
                        options: {
                            name: selectedId ? `${selectedId}_${v.columnName}` : v.columnName,
                            parentId: v.parentId || selectedId,
                            label: v.nameCn,
                            fieldAttribute: v.columnName,
                            labelAlign: 'label-right-align',
                            defaultValue: null,
                            placeholder: '',
                            columnWidth: '200px',
                            size: '',
                            labelWidth: null,
                            labelHidden: false,
                            readonly: false,
                            disabled: false,
                            hidden: false,
                            clearable: true,
                            editable: false,
                            format: 'HH:mm:ss',  //时间格式
                            required: false,
                            requiredHint: '',
                            validation: v.columnValidation || v.attributeTypeName,
                            validationHint: '',
                            //-------------------
                            customClass: '',  //自定义css类名
                            labelIconClass: null,
                            labelIconPosition: 'rear',
                            labelTooltip: null,
                            //-------------------
                            onCreated: '',
                            onMounted: '',
                            onChange: '',
                            onFocus: '',
                            onBlur: '',
                            onValidate: '',
                        },
                    }
                }
                if (v.attributeTypeName === 'datetime') {
                    newWidget =
                    {
                        type: 'date',
                        icon: 'date-field',
                        formItemFlag: true,
                        id: "number" + tempId,
                        options: {
                            name: selectedId ? `${selectedId}_${v.columnName}` : v.columnName,
                            parentId: v.parentId || selectedId,
                            label: v.nameCn,
                            fieldAttribute: v.columnName,
                            labelAlign: 'label-right-align',
                            type: 'datetime',
                            defaultValue: null,
                            placeholder: '',
                            columnWidth: '200px',
                            size: '',
                            labelWidth: null,
                            labelHidden: false,
                            readonly: false,
                            disabled: false,
                            hidden: false,
                            clearable: true,
                            editable: false,
                            format: 'yyyy-MM-dd HH:mm:ss',  //日期显示格式
                            valueFormat: 'yyyy-MM-dd HH:mm:ss',  //日期对象格式
                            required: false,
                            requiredHint: '',
                            validation: v.columnValidation || v.attributeTypeName,
                            validationHint: '',
                            //-------------------
                            customClass: '',  //自定义css类名
                            labelIconClass: null,
                            labelIconPosition: 'rear',
                            labelTooltip: null,
                            //-------------------
                            onCreated: '',
                            onMounted: '',
                            onChange: '',
                            onFocus: '',
                            onBlur: '',
                            onValidate: '',
                        },
                    }
                }
            }
            return newWidget;
        },

        // 根据属性生成json数据
        getFormByType(data) {
            const newWidgetList = data.map(v => {
                let newWidget = null;
                newWidget = this.getWidgetByType(v, this.selectedId)
                return newWidget;
            })
            return newWidgetList.filter(k => !!k)
        },

        addFieldByData(parentList, indexOfParentList, data) {
            const newWidget = this.getFormByType(data);
            newWidget.push(this.addButtonWidget());
            const newData = {
                ...this.selectedWidget,
                widgetList: newWidget,
            };
            parentList.splice(indexOfParentList, 1, newData)
        },
        addParentFieldByData(parentWidget, data) {
            const newWidget = this.getFormByType(data);
            newWidget.push(this.addButtonWidget());
            parentWidget.widgetList=[...newWidget]
        },

        addButtonWidget(widgetList) {
            let tmpId = generateId();
            let tmpId2 = generateId();
            let tmpId3 = generateId();

            const newData = {
                type: "box-container",
                category: "container",
                icon: "card",
                merged: false,
                id: 'box-container-' + tmpId,
                options: {
                    name: 'boxContainer' + tmpId,
                    label: 'boxContainer' + tmpId,
                    customClass: "",
                    initStyle: {
                        height: "38",
                        minHeight: "38",
                        width: "100%",
                        backgroundColor: "#FFF",
                        color: "#000",
                        padding: "0",
                        margin: "0",
                        textAlign: "right"
                    },
                },
                displayName: "空容器",
                widgetList: widgetList || [
                    {
                        type: 'button',
                        icon: 'button',
                        formItemFlag: false,
                        id: 'button' + tmpId2,
                        options: {
                            name: 'button' + tmpId2,
                            columnWidth: '200px',
                            size: 'small',
                            displayStyle: 'block',
                            displayStyle: "inline-block",
                            hidden: false,
                            icon: null,
                            label: "取消",
                            type: '',
                            plain: false,
                            round: false,
                            circle: false,
                            icon: null,
                            //-------------------
                            customClass: '',  //自定义css类名
                            //-------------------
                            onClick: '',
                        },
                    },
                    {
                        type: 'button',
                        icon: 'button',
                        formItemFlag: false,
                        id: 'button' + tmpId3,
                        options: {
                            name: 'button' + tmpId3,
                            columnWidth: '200px',
                            size: 'small',
                            displayStyle: 'block',
                            displayStyle: "inline-block",
                            hidden: false,
                            icon: null,
                            label: "确定",
                            type: "primary",
                            plain: false,
                            round: false,
                            circle: false,
                            icon: null,
                            //-------------------
                            customClass: '',  //自定义css类名
                            //-------------------
                            onClick: 'save',
                        },
                    }
                ]
            }
            return newData;
        },
        addTableButtonWidget(widgetList) {
            let tmpId = generateId();
            let tmpId2 = generateId();
            let tmpId3 = generateId();
            let tmpId4 = generateId();
            let tmpId5 = generateId();

            const newData = {
                type: "box-container",
                category: "container",
                icon: "card",
                merged: false,
                id: 'box-container-' + tmpId,
                options: {
                    name: 'boxContainer' + tmpId,
                    label: '操作栏',
                    customClass: "",
                    initStyle: {
                        height: "38",
                        minHeight: "38",
                        width: "100%",
                        backgroundColor: "#FFF",
                        color: "#000",
                        padding: "0",
                        margin: "0",
                        textAlign: "left"
                    },
                },
                displayName: "空容器",
                widgetList: widgetList || [
                    // {
                    //     type: 'button',
                    //     icon: 'button',
                    //     formItemFlag: false,
                    //     id: 'button' + tmpId2,
                    //     options: {
                    //         name: 'button' + tmpId2,
                    //         columnWidth: '200px',
                    //         size: 'small',
                    //         displayStyle: 'block',
                    //         displayStyle: "inline-block",
                    //         hidden: false,
                    //         icon: null,
                    //         label: "Search",
                    //         type: '',
                    //         plain: false,
                    //         round: false,
                    //         circle: false,
                    //         icon: null,
                    //         //-------------------
                    //         customClass: '',  //自定义css类名
                    //         //-------------------
                    //         onClick: 'onSearch',
                    //     },
                    // },
                    {
                        type: 'operate-button',
                        icon: 'button',
                        formItemFlag: false,
                        id: 'operate-button' + tmpId3,
                        options: {
                            name: 'operate-button' + tmpId3,
                            columnWidth: '200px',
                            size: 'small',
                            displayStyle: 'block',
                            displayStyle: "inline-block",
                            hidden: false,
                            icon: null,
                            label: "New",
                            type: "default",
                            plain: false,
                            round: false,
                            circle: false,
                            icon: null,
                            operateType:'add',
                            //-------------------
                            customClass: '',  //自定义css类名
                            //-------------------
                            onBtnClick: {},
                        },
                    },
                    {
                        type: 'operate-button',
                        icon: 'button',
                        formItemFlag: false,
                        id: 'operate-button' + tmpId4,
                        options: {
                            name: 'operate-button' + tmpId4,
                            columnWidth: '200px',
                            size: 'small',
                            displayStyle: 'block',
                            displayStyle: "inline-block",
                            hidden: false,
                            icon: null,
                            label: "Edit",
                            type: "default",
                            plain: false,
                            round: false,
                            circle: false,
                            icon: null,
                            operateType:'edit',
                            //-------------------
                            customClass: '',  //自定义css类名
                            //-------------------
                            onBtnClick: {},
                        },
                    },
                    {
                        type: 'operate-button',
                        icon: 'button',
                        formItemFlag: false,
                        id: 'operate-button' + tmpId5,
                        options: {
                            name: 'operate-button' + tmpId5,
                            columnWidth: '200px',
                            size: 'small',
                            displayStyle: 'block',
                            displayStyle: "inline-block",
                            hidden: false,
                            icon: null,
                            label: "Delete",
                            type: "default",
                            plain: false,
                            round: false,
                            circle: false,
                            icon: null,
                            operateType:'delete',
                            //-------------------
                            customClass: '',  //自定义css类名
                            //-------------------
                            onBtnClick: {},
                        },
                    },
                ]
            }
            return newData;
        },

        addContainer() {
            //递归方法Data
            const recursionFunc = (data, currentData, updateData) => {
                for (let i = 0, len = data.length; i < len; i++) {

                    if (data[i].id === currentData.id) {
                        data[i] = updateData;
                    } else {
                        if (data[i].children) {
                            recursionFunc(data[i].children, updateData)
                        }
                    }
                }
            }
            let tmpId = generateId()
            const newBox = {
                type: "box-container",
                category: "container",
                icon: "card",
                widgetList: [this.selectedWidget],
                merged: false,
                id: 'box-container-' + tmpId,
                options: {
                    name: 'boxContainer' + tmpId,
                    label: 'boxContainer' + tmpId,
                    customClass: "",
                    initStyle: {
                        height: "38",
                        minHeight: "38",
                        width: "100%",
                        backgroundColor: "#FFF",
                        color: "#000",
                        padding: "0",
                        margin: "0",
                    },
                },
                displayName: "空容器",
            };
            // 找到选中节点并替换
            recursionFunc(this.widgetList, this.selectedWidget, newBox);
            this.setSelected(newBox);
        },

        copyNewContainerWidgetComp(widgetList) {
            const newList = widgetList.map(origin => {
                let newCon = deepClone(origin)
                newCon.id = newCon.type.replace(/-/g, '') + generateId()
                newCon.options.name = newCon.id
                if (newCon.type === 'grid') {
                    let newCol = deepClone(this.getContainerByType('grid-col'));
                    let tmpId = generateId();
                    newCol.id = 'grid-col-' + tmpId;
                    newCon.cols.forEach(v => {
                        let tmpId2 = generateId();
                        v.id = 'grid-col-' + tmpId2;
                        if (v.widgetList.length > 0) {
                            v.widgetList.forEach(k => {
                                let tmpId3 = generateId();
                                k.id = k.type + tmpId3;
                            })
                        }
                    })
                } else if (newCon.type === 'table') {
                    let newRow = { cols: [] }
                    newRow.id = 'table-row-' + generateId()
                    newRow.merged = false
                    let newCell = deepClone(this.getContainerByType('table-cell'))
                    newCell.id = 'table-cell-' + generateId()
                    newCell.options.name = newCell.id
                    newCell.merged = false
                    newCell.options.colspan = 1
                    newCell.options.rowspan = 1
                    newRow.cols.push(newCell)
                    newCon.rows.push(newRow)
                } else if (newCon.type === 'data-column') {
                    let newRow = { cols: [] }
                    newRow.id = 'table-row-' + generateId()
                    newRow.merged = false
                    let newCell = deepClone(this.getContainerByType('table-cell'))
                    newCell.id = 'table-cell-' + generateId()
                    newCell.options.name = newCell.id
                    newCell.merged = false
                    newCell.options.colspan = 1
                    newCell.options.rowspan = 1
                    newRow.cols.push(newCell)
                    newCon.rows.push(newRow)
                } else if (newCon.type === 'tab') {
                    let newTabPane = deepClone(this.getContainerByType('tab-pane'))
                    newTabPane.id = 'tab-pane-' + generateId()
                    newTabPane.options.name = 'tab1'
                    newTabPane.options.label = 'tab 1'
                    newCon.tabs.push(newTabPane)
                }
                //newCon.options.customClass = []

                delete newCon.displayName
                return newCon
            });
            // 添加父级空容器
            const containerBox = {
                type: 'box-container',
                category: 'container',
                icon: 'card',
                widgetList: [...newList],
                merged: false,
                id: 'box-container-' + generateId(),
                options: {
                    name: '',
                    customClass: '',  //自定义css类名
                    initStyle: {
                        height: "38",
                        minHeight: '38',
                        width: "100%",
                        backgroundColor: '#FFF',
                        color: '#000',
                        padding: "0",
                        margin: "0",
                    }, // 添加的样式
                }
            };
            return containerBox
        },

        copyNewContainerWidget(origin) {
            let newCon = deepClone(origin)
            newCon.id = newCon.type.replace(/-/g, '') + generateId()
            newCon.options.name = newCon.id
            if (newCon.type === 'grid') {
                let newCol = deepClone(this.getContainerByType('grid-col'))
                let tmpId = generateId()
                newCol.id = 'grid-col-' + tmpId
                newCol.options.name = 'gridCol' + tmpId
                newCon.cols.push(newCol)
                //
                newCol = deepClone(newCol)
                tmpId = generateId()
                newCol.id = 'grid-col-' + tmpId
                newCol.options.name = 'gridCol' + tmpId
                newCon.cols.push(newCol)
            } else if (newCon.type === 'table') {
                let newRow = { cols: [] }
                newRow.id = 'table-row-' + generateId()
                newRow.merged = false
                let newCell = deepClone(this.getContainerByType('table-cell'))
                newCell.id = 'table-cell-' + generateId()
                newCell.options.name = newCell.id
                newCell.merged = false,
                newCell.options.colspan = 1;
                newCell.options.fieldAttribute = '';
                newCell.options.rowspan = 1;
                newRow.cols.push(newCell)
                newCon.rows.push(newRow)
            } else if (newCon.type === 'data-column') {
                let newRow = { cols: [] }
                newRow.id = 'table-row-' + generateId()
                newRow.merged = false
                let newCell = deepClone(this.getContainerByType('table-column'))
                newCell.id = 'table-column-' + generateId()
                newCell.options.name = newCell.id
                newCell.merged = false
                newCell.options.colspan = 1
                newCell.options.rowspan = 1
                newRow.cols.push(newCell)
                newCon.rows.push(newRow)
            } else if (newCon.type === 'tab') {
                let newTabPane = deepClone(this.getContainerByType('tab-pane'))
                newTabPane.id = 'tab-pane-' + generateId()
                newTabPane.options.name = 'tab1'
                newTabPane.options.label = 'tab 1'
                newCon.tabs.push(newTabPane)
            }
            //newCon.options.customClass = []

            delete newCon.displayName
            return newCon
        },

      
        addDataScript(newCon) {
            // data处理
            if (this.pageScript.data) {
                const dataInfo = JSON.parse(this.pageScript.data);
                if (dataInfo[newCon.id]) {
                    return
                }
                dataInfo[newCon.id] = []
                this.pageScript.data = JSON.stringify(dataInfo);
            } else {
                const dataInfo = {};
                dataInfo[newCon.id] = []
                this.pageScript.data = JSON.stringify(dataInfo);
            }
            // method处理
             this.pageScript.methods.push({
                funBody:'',
                funName:`get${titleCase(newCon.id)}`,
                funRemark:'',
                id: generateId(),
             });

             // 为新加容器绑定数据源
             newCon.options.dataSource=`get${titleCase(newCon.id)}`;
        },

        addContainerByDbClick(container) {
            let newCon = this.copyNewContainerWidget(container)
            // 新增数据容器
            if (newCon.type === 'data-view') {
                this.addDataScript(newCon)
            }

            this.widgetList.push(newCon)
            this.setSelected(newCon)
        },

        addFieldByDbClick(widget) {
            let newWidget = this.copyNewFieldWidget(widget)
            if (!!this.selectedWidget && this.selectedWidget.type === 'tab') {
                //获取当前激活的tabPane
                let activeTab = this.selectedWidget.tabs[0]
                this.selectedWidget.tabs.forEach(tabPane => {
                    if (tabPane.options.active) {
                        activeTab = tabPane
                    }
                })

                !!activeTab && activeTab.widgetList.push(newWidget)
            } else if (!!this.selectedWidget && !!this.selectedWidget.widgetList) {
                this.selectedWidget.widgetList.push(newWidget)
            } else {
                this.widgetList.push(newWidget)
            }

            this.setSelected(newWidget)
            this.emitHistoryChange()
        },

        deleteColOfGrid(gridWidget, colIdx) {
            if (!!gridWidget && !!gridWidget.cols) {
                gridWidget.cols.splice(colIdx, 1)
            }
        },

        addNewColOfGrid(gridWidget) {
            const cols = gridWidget.cols
            let newGridCol = deepClone(this.getContainerByType('grid-col'))
            let tmpId = generateId()
            newGridCol.id = 'grid-col-' + tmpId
            newGridCol.options.name = 'gridCol' + tmpId
            if ((!!cols) && (cols.length > 0)) {
                let spanSum = 0
                cols.forEach((col) => {
                    spanSum += col.options.span
                })

                if (spanSum >= 24) {
                    //this.$message.info('列栅格之和超出24')
                    gridWidget.cols.push(newGridCol)
                } else {
                    newGridCol.options.span = (24 - spanSum) > 12 ? 12 : (24 - spanSum)
                    gridWidget.cols.push(newGridCol)
                }
            } else {
                gridWidget.cols = [newGridCol]
            }
        },

        addTabPaneOfTabs(tabsWidget) {
            const tabPanes = tabsWidget.tabs
            let newTabPane = deepClone(this.getContainerByType('tab-pane'))
            newTabPane.id = 'tab-pane-' + generateId()
            newTabPane.options.name = newTabPane.id
            newTabPane.options.label = 'tab ' + (tabPanes.length + 1)
            tabPanes.push(newTabPane)
        },

        deleteTabPaneOfTabs(tabsWidget, tpIdx) {
            tabsWidget.tabs.splice(tpIdx, 1)
        },
        addTabCollapse(tabsWidget) {
            const tabPanes = tabsWidget.tabs
            let newTabPane = deepClone(this.getContainerByType('tab-pane'))
            newTabPane.id = 'tab-pane-' + generateId()
            newTabPane.options.name = newTabPane.id,
                newTabPane.title = 'collapse ' + (tabPanes.length + 1)
            newTabPane.options.label = 'tab ' + (tabPanes.length + 1)
            tabPanes.push(newTabPane)
        },

        deleteTabPaneOfCollapse(tabsWidget, tpIdx) {
            tabsWidget.tabs.splice(tpIdx, 1)
        },


        emitEvent(evtName, evtData) {  //用于兄弟组件发射事件
            this.vueInstance.$emit(evtName, evtData)
        },

        handleEvent(evtName, callback) {  //用于兄弟组件接收事件
            this.vueInstance.$on(evtName, (data) => callback(data))
        },

        setCssClassList(cssClassList) {
            this.cssClassList = cssClassList
        },

        getCssClassList() {
            return this.cssClassList
        },

        registerFormWidget(formWidget) {
            this.formWidget = formWidget
        },

        initHistoryData() {
            this.loadFormContentFromStorage()
            this.historyData.index++
            this.historyData.steps[this.historyData.index] = ({
                dataSource: deepClone(this.dataSource),
                widgetList: deepClone(this.widgetList),
                formConfig: deepClone(this.formConfig),
                pageScript: deepClone(this.pageScript)
            })
        },

        emitHistoryChange() {
            //console.log('------------', 'Form history changed!')

            if (this.historyData.index === this.historyData.maxStep - 1) {
                this.historyData.steps.shift()
            } else {
                this.historyData.index++
            }

            this.historyData.steps[this.historyData.index] = ({
                dataSource: deepClone(this.dataSource),
                widgetList: deepClone(this.widgetList),
                formConfig: deepClone(this.formConfig),
                pageScript: deepClone(this.pageScript)
            })

            this.saveFormContentToStorage()

            if (this.historyData.index < this.historyData.steps.length - 1) {
                this.historyData.steps = this.historyData.steps.slice(0, this.historyData.index + 1)
            }

            //console.log('history', this.historyData.index)
        },

        saveCurrentHistoryStep() {
            this.historyData.steps[this.historyData.index] = deepClone({
                dataSource: this.dataSource,
                widgetList: this.widgetList,
                formConfig: this.formConfig,
                pageScript: this.pageScript,
            })

            this.saveFormContentToStorage()
        },

        undoHistoryStep() {
            if (this.historyData.index !== 0) {
                this.historyData.index--
            }
            //console.log('undo', this.historyData.index)

            this.dataSource = deepClone(this.historyData.steps[this.historyData.index].dataSource)
            this.widgetList = deepClone(this.historyData.steps[this.historyData.index].widgetList)
            this.formConfig = deepClone(this.historyData.steps[this.historyData.index].formConfig)
            this.pageScript = deepClone(this.historyData.steps[this.historyData.index].pageScript)
        },

        redoHistoryStep() {
            if (this.historyData.index !== (this.historyData.steps.length - 1)) {
                this.historyData.index++
            }
            //console.log('redo', this.historyData.index)

            this.dataSource = deepClone(this.historyData.steps[this.historyData.index].dataSource)
            this.widgetList = deepClone(this.historyData.steps[this.historyData.index].widgetList)
            this.formConfig = deepClone(this.historyData.steps[this.historyData.index].formConfig)
            this.pageScript = deepClone(this.historyData.steps[this.historyData.index].pageScript)
        },

        undoEnabled() {
            return (this.historyData.index > 0) && (this.historyData.steps.length > 0)
        },

        redoEnabled() {
            return this.historyData.index < (this.historyData.steps.length - 1)
        },

        saveFormContentToStorage() {
            window.localStorage.setItem('data__source__backup', JSON.stringify(this.dataSource))
            window.localStorage.setItem('widget__list__backup', JSON.stringify(this.widgetList))
            window.localStorage.setItem('form__config__backup', JSON.stringify(this.formConfig))
            window.localStorage.setItem('page__script__backup', JSON.stringify(this.pageScript))
        },

        loadFormContentFromStorage() {
            let dataSourceBackup = window.localStorage.getItem('data__source__backup')
            if (dataSourceBackup) {
                this.dataSource = JSON.parse(dataSourceBackup)
            }

            let widgetListBackup = window.localStorage.getItem('widget__list__backup')
            if (widgetListBackup) {
                this.widgetList = JSON.parse(widgetListBackup)
            }

            let formConfigBackup = window.localStorage.getItem('form__config__backup')
            if (formConfigBackup) {
                //this.formConfig = JSON.parse(formConfigBackup)
                overwriteObj(this.formConfig, JSON.parse(formConfigBackup))  /* 用=赋值，会导致inject依赖注入的formConfig属性变成非响应式 */
            }

            let pageScriptBackup = window.localStorage.getItem('page__script__backup')
            if (pageScriptBackup) {
                this.pageScript = JSON.parse(pageScriptBackup)
            }
        },
    }
}
